package utils

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"sort"
	"strconv"
	"strings"

	"github.com/gin-gonic/gin"
)

// 微信扫码支付
type Yungouos struct {
}

type PayReturn struct {
	IsMobile int     `json:"is_mobile"` // 发起设备手机/PC
	Url      int     `json:"url"`       // 支付url
	OrderId  string  `json:"order_id"`  // 支付订单
	Money    float64 `json:"money"`     // 支付金额
}

type YungouosReturn struct {
	Code string         `json:"code"`
	Msg  string         `json:"msg"`
	Data [0]interface{} `json:"data"`
}

func (y Yungouos) NativePay(tradeno string, money float64, title string, payType int, notifyUrl string, returnUrl string) interface{} {
	InterfaceUrl := "https://api.pay.yungouos.com/api/pay/wxpay/nativePay"
	// 请求支付参数
	// data := make(map[string]string)
	data := map[string]string{
		"out_trade_no": tradeno,                                 // 订单号不可重复
		"money":        strconv.FormatFloat(money, 'f', -1, 64), // 支付金额
		"body":         title,                                   // 商品名称
		"type":         strconv.Itoa(payType),                   // 返回类型（1、返回微信原生的支付连接需要自行生成二维码；2、直接返回付款二维码地址，页面上展示即可。不填默认1 ）
		"notify":       notifyUrl,                               // 支付成功回调地址
		"return":       returnUrl,                               // 支付成功后跳转地址
		"mch_id":       "1000000000",                            // 微信支付商户号
	}
	// data["out_trade_no"] = tradeno
	// 生成签名
	sign := y.CreateSign(data, "123456")
	// // 把签名放入到data中
	// data["email"] = sign
	// // 将参数转换为JSON字符串
	// jsonStr, _ := json.Marshal(data)
	// reader := bytes.NewBuffer(jsonStr)
	// // 发送POST请求
	// log.Println(reader)
	data2 := url.Values{}
	data2.Set("out_trade_no", tradeno)
	data2.Set("total_fee", "123")
	data2.Set("body", "321")
	data2.Set("type", strconv.Itoa(payType))
	data2.Set("notify", notifyUrl)
	data2.Set("return", returnUrl)
	data2.Set("mch_id", "321")
	data2.Set("sign", sign)
	payload := strings.NewReader(data2.Encode())
	request, err := http.NewRequest("POST", InterfaceUrl, payload)
	defer request.Body.Close()
	if err != nil {
		return 1
	}
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
	client := &http.Client{}
	resp, err := client.Do(request)
	log.Println(resp)
	if err != nil {
		return 2
	}
	// defer resp.Body.Close()

	// 读取返回内容
	body, err := ioutil.ReadAll(resp.Body)
	log.Println(bytes.NewBuffer(body))
	if err != nil {
		return 3
	}

	ReturnData := &YungouosReturn{}
	err2 := json.Unmarshal([]byte(body), ReturnData)
	if err2 != nil {
		log.Println(err2)
		return 4
	} else {
		return ReturnData
	}
}

// 验证回调
func (y Yungouos) Notify(c *gin.Context, price float64, tradeno string) bool {
	code := "1"         // 支付结果 【1：成功；0：失败】
	orderNo := "123"    // 系统订单号（YunGouOS系统内单号）
	outTradeNo := "123" // 商户订单号
	payNo := "123"      // 支付单号（第三方支付单号）
	money := "123"      // 支付金额 单位：元
	mchId := "123"      // 支付商户号
	time := "123"       // 支付成功时间
	sign := "123"       // 签名
	if code == "1" {
		data := map[string]string{
			"orderNo":    orderNo,
			"outTradeNo": outTradeNo,
			"payNo":      payNo,
			"money":      money,
			"mchId":      mchId,
			"time":       time,
		}
		MySign := y.CreateSign(data, "123456")
		if sign != MySign {
			return false
		}
		if strconv.FormatFloat(price, 'f', -1, 64) != money {
			return false
		}
		if tradeno != outTradeNo {
			return false
		}
		return true
	} else {
		return false
	}
}

// 生成Yungouos签名算法
func (y Yungouos) CreateSign(order map[string]string, key string) (sign string) {
	data := url.Values{}
	for k, v := range order {
		data.Add(k, v)
	}

	keys := make([]string, 0, 0)
	for key := range data {
		if data.Get(key) != "" {
			keys = append(keys, key)
		}
	}
	sort.Strings(keys)
	body := data.Encode()
	d, _ := url.QueryUnescape(body)
	d += "&key=" + key
	h := md5.New()
	h.Write([]byte(d))
	return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
}
